/*
 * Copyright 2022 The Open Islands Authors. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.openislands.oi.manager.union;


public class UnionPipeline<Params> {
    /***
     * Head Context
     * Usually an empty define that passes Params to the next context
     */
    private final UnionHandlerContext<?, ?, Params> headContext;

    public UnionPipeline(Params params) {
        this.headContext = new UnionHandlerContext<>(emptyDefine(), ($, object) -> params);
    }

    public <NT, NR> UnionHandlerContext<NT, Params, NR> addNext(Class<NT> mapperClass, UnionHandler<NT, Params, NR> handler) {
        return headContext.addNext(mapperClass, handler);
    }

    public <NT, NR> UnionHandlerContext<NT, Params, NR> addNextS(Class<NT> mapperClass, UnionHandler.SingleHandler<NT, NR> handler) {
        return this.addNext(mapperClass, (target, params) -> handler.handle(target));
    }

    public UnionHandlerContext<?, ?, Params> getHeadContext() {
        return headContext;
    }

    public static <Params> UnionPipeline<Params> create(Params params) {
        return new UnionPipeline<>(params);
    }

    @SuppressWarnings("unchecked")
    public static <Target> Class<Target> emptyDefine() {
        return ((Class<Target>) EmptyDefine.class);
    }

    public static class EmptyDefine {
        public <T> T define(T t) {
            return t;
        }
    }
}
